#ifndef _MCU_GPIO_H_
#define _MCU_GPIO_H_

#include "..\ARM\typedef.h"

// 寄存器是0~22，规格书把编号重新打乱
typedef enum _gpio_pin_t
{
    GPIO_P00_PA0   =   0,     P0_PA0  =  0,    PA0 = 0, // P00
    GPIO_P01_PA1   =   1,     P1_PA1  =  1,    PA1 = 1, // P01
    GPIO_P02_PA2   =   2,     P2_PA2  =  2,    PA2 = 2, // P02
    GPIO_P03_PA3   =   3,     P3_PA3  =  3,    PA3 = 3, // P03
    GPIO_P07_PA4   =   4,     P7_PA4  =  4,    PA4 = 4, // P07
    GPIO_P09_PA5   =   5,     P9_PA5  =  5,    PA5 = 5, // P09
    GPIO_P10_PA6   =   6,     P10_PA6  =  6,   PA6 = 6, // P10
    GPIO_P11_PA7   =   7,     P11_PA7  =  7,   PA7 = 7,     APIN_0 = 7,  AIO0 = 7, // P11
    GPIO_P14_PA8   =   8,     P14_PA8  =  8,   PA8 = 8,     APIN_1 = 8,  AIO3 = 8, // P14
    GPIO_P15_PA9   =   9,     P15_PA9  =  9,   PA9 = 9,     APIN_2 = 9,  AIO4 = 9, // P15
    GPIO_P16_PA10   =   10,   P16_PA10  =  10, PA10 = 10,   APIN_3 = 10, // P16
    GPIO_P17_PA11   =   11,   P17_PA11  =  11, PA11 = 11,   APIN_4 = 11, // P17
    GPIO_P18_PA12   =   12,   P18_PA12  =  12, PA12 = 12,   APIN_5 = 12, AIO7 = 12, // P18
    GPIO_P20_PA13   =   13,   P20_PA13  =  13, PA13 = 13,   APIN_6 = 13, AIO9 = 13, // P20
    GPIO_P23_PA14   =   14,   P23_PA14  =  14, PA14 = 14,   APIN_7 = 14, AIO1 = 14, // P23
    GPIO_P24_PA15   =   15,   P24_PA15  =  15, PA15 = 15,   APIN_8 = 15, AIO2 = 15, // P24
    GPIO_P25_PA16   =   16,   P25_PA16  =  16, PA16 = 16,   APIN_9 = 16, AIO8 = 16, // P25
    GPIO_P26_PA17   =   17,   P26_PA17  =  17, PA17 = 17, // P26
    GPIO_P27_PA18   =   18,   P27_PA18  =  18, PA18 = 18, // P27
    GPIO_P31_PA19   =   19,   P31_PA19  =  19, PA19 = 19, // P31
    GPIO_P32_PA20   =   20,   P32_PA20  =  20, PA20 = 20, // P32
    GPIO_P33_PA21   =   21,   P33_PA21  =  21, PA21 = 21, // P33
    GPIO_P34_PA22   =   22,   P34_PA22  =  22, PA22 = 22, // P34
}gpio_pin_t;

// 方向
typedef enum _gpio_dir_t
{
    GPIO_DIR_INPUT = 0,
    GPIO_DIR_OUTPUT = 1
}gpio_dir_t;

// 中断模式
typedef enum _gpio_int_mode_t
{
    GPIO_IM_LEVEL = 0,  // 电平触发
    GPIO_IM_EDGE = 1    // 边沿触发
}gpio_int_mode_t;

// 中断极性
typedef enum _gpio_int_polarity_t
{
    GPIO_IP_NEGATIVE = 0,   // 低电平或下降沿
    GPIO_IP_POSITIVE = 1    // 高电平或上升沿
}gpio_int_polarity_t;

// 中断配置参数
typedef struct _gpio_int_param_t
{
    u8 Enable;    // 1：使能中断
    gpio_int_mode_t Mode;   // 中断模式
    gpio_int_polarity_t Polarity;   // 中断极性
}gpio_int_param_t;

typedef enum _gpio_pul_t
{
    GPIO_PUL_NONE = 0,  // 无上下拉（浮空）
    GPIO_PUL_UP_S = 1,  // 强上拉
    GPIO_PUL_UP = 2,    // 弱上拉
    GPIO_PUL_DOWN = 3   // 下拉
}gpio_pul_t;

/**
 * 按照配置文件初始化GPIO。
*/
void Gpio_Init();

/**
 * 设置PIN方向，此函数效率较低，建议对速度有要求时使用操作寄存器或者伪函数替代。
 * @param   pin     管脚
 * @param   dir     方向
*/
void Gpio_SetDir(gpio_pin_t pin, gpio_dir_t dir);

/**
 * 设置PIN输出电平，此函数效率较低，建议对速度有要求时使用操作寄存器或者伪函数替代。
 * @param   pin     管脚
 * @param   level   电平
*/
void Gpio_SetLevel(gpio_pin_t pin, u8 level);

/**
 * 获取PIN输入电平，此函数效率较低，建议对速度有要求时使用操作寄存器或者伪函数替代。
 * @param   pin     管脚
 * @return          电平
*/
u8 Gpio_GetLevel(gpio_pin_t pin);

/**
 * 设置管脚中断参数
 * @param   pin     管脚
 * @param   int_param   中断参数的指针
*/
void Gpio_SetInt(gpio_pin_t pin, gpio_int_param_t * int_param);

/**
 * 获取中断标记。一般在中断服务函数中在清除中断标记之前调用。
 * @param   pin     管脚
 * @return          1：发生了中断。
*/
u8 Gpio_GetIntFlag(gpio_pin_t pin);

/**
 * 清除所有GPIO的中断标记。
*/
#define Gpio_ClrIntFlags()  AP_GPIO->ICR = 0XFFFFFFFF

/**
 * 设置上下拉。
 * 因寄存器特别分散且无规律，此函数效率很低，建议对速度有要求时使用对应管脚的伪函数替代。
 * @param   pin     管脚
 * @param   pul     上下拉情况
*/
void Gpio_SetPul(gpio_pin_t pin, gpio_pul_t pul);


/**
 * 快速设置 P00 方向。
 * @param   dir 0:输入；1:输出。
*/
#define Gpio_SetDirP00(dir)     AP_GPIO->DIR_f.DIR0 = dir
#define Gpio_SetDirP01(dir)     AP_GPIO->DIR_f.DIR1 = dir
#define Gpio_SetDirP02(dir)     AP_GPIO->DIR_f.DIR2 = dir
#define Gpio_SetDirP03(dir)     AP_GPIO->DIR_f.DIR3 = dir
#define Gpio_SetDirP07(dir)     AP_GPIO->DIR_f.DIR4 = dir
#define Gpio_SetDirP09(dir)     AP_GPIO->DIR_f.DIR5 = dir
#define Gpio_SetDirP10(dir)     AP_GPIO->DIR_f.DIR6 = dir
#define Gpio_SetDirP11(dir)     AP_GPIO->DIR_f.DIR7 = dir
#define Gpio_SetDirP14(dir)     AP_GPIO->DIR_f.DIR8 = dir
#define Gpio_SetDirP15(dir)     AP_GPIO->DIR_f.DIR9 = dir
#define Gpio_SetDirP16(dir)     AP_GPIO->DIR_f.DIR10 = dir
#define Gpio_SetDirP17(dir)     AP_GPIO->DIR_f.DIR11 = dir
#define Gpio_SetDirP18(dir)     AP_GPIO->DIR_f.DIR12 = dir
#define Gpio_SetDirP20(dir)     AP_GPIO->DIR_f.DIR13 = dir
#define Gpio_SetDirP23(dir)     AP_GPIO->DIR_f.DIR14 = dir
#define Gpio_SetDirP24(dir)     AP_GPIO->DIR_f.DIR15 = dir
#define Gpio_SetDirP25(dir)     AP_GPIO->DIR_f.DIR16 = dir
#define Gpio_SetDirP26(dir)     AP_GPIO->DIR_f.DIR17 = dir
#define Gpio_SetDirP27(dir)     AP_GPIO->DIR_f.DIR18 = dir
#define Gpio_SetDirP31(dir)     AP_GPIO->DIR_f.DIR19 = dir
#define Gpio_SetDirP32(dir)     AP_GPIO->DIR_f.DIR20 = dir
#define Gpio_SetDirP33(dir)     AP_GPIO->DIR_f.DIR21 = dir
#define Gpio_SetDirP34(dir)     AP_GPIO->DIR_f.DIR22 = dir

/**
 * 快速设置 P00 电平
 * @param   level 电平
*/
#define Gpio_SetLevelP00(level)     AP_GPIO->ODR_f.ODR0 = level
#define Gpio_SetLevelP01(level)     AP_GPIO->ODR_f.ODR1 = level
#define Gpio_SetLevelP02(level)     AP_GPIO->ODR_f.ODR2 = level
#define Gpio_SetLevelP03(level)     AP_GPIO->ODR_f.ODR3 = level
#define Gpio_SetLevelP07(level)     AP_GPIO->ODR_f.ODR4 = level
#define Gpio_SetLevelP09(level)     AP_GPIO->ODR_f.ODR5 = level
#define Gpio_SetLevelP10(level)     AP_GPIO->ODR_f.ODR6 = level
#define Gpio_SetLevelP11(level)     AP_GPIO->ODR_f.ODR7 = level
#define Gpio_SetLevelP14(level)     AP_GPIO->ODR_f.ODR8 = level
#define Gpio_SetLevelP15(level)     AP_GPIO->ODR_f.ODR9 = level
#define Gpio_SetLevelP16(level)     AP_GPIO->ODR_f.ODR10 = level
#define Gpio_SetLevelP17(level)     AP_GPIO->ODR_f.ODR11 = level
#define Gpio_SetLevelP18(level)     AP_GPIO->ODR_f.ODR12 = level
#define Gpio_SetLevelP20(level)     AP_GPIO->ODR_f.ODR13 = level
#define Gpio_SetLevelP23(level)     AP_GPIO->ODR_f.ODR14 = level
#define Gpio_SetLevelP24(level)     AP_GPIO->ODR_f.ODR15 = level
#define Gpio_SetLevelP25(level)     AP_GPIO->ODR_f.ODR16 = level
#define Gpio_SetLevelP26(level)     AP_GPIO->ODR_f.ODR17 = level
#define Gpio_SetLevelP27(level)     AP_GPIO->ODR_f.ODR18 = level
#define Gpio_SetLevelP31(level)     AP_GPIO->ODR_f.ODR19 = level
#define Gpio_SetLevelP32(level)     AP_GPIO->ODR_f.ODR20 = level
#define Gpio_SetLevelP33(level)     AP_GPIO->ODR_f.ODR21 = level
#define Gpio_SetLevelP34(level)     AP_GPIO->ODR_f.ODR22 = level

/**
 * 快速获取 P00 电平（输入模式才有效）
 * @return   电平
*/
#define Gpio_GetLevelP00()     AP_GPIO->IDR_f.IDR0
#define Gpio_GetLevelP01()     AP_GPIO->IDR_f.IDR1
#define Gpio_GetLevelP02()     AP_GPIO->IDR_f.IDR2
#define Gpio_GetLevelP03()     AP_GPIO->IDR_f.IDR3
#define Gpio_GetLevelP07()     AP_GPIO->IDR_f.IDR4
#define Gpio_GetLevelP09()     AP_GPIO->IDR_f.IDR5
#define Gpio_GetLevelP10()     AP_GPIO->IDR_f.IDR6
#define Gpio_GetLevelP11()     AP_GPIO->IDR_f.IDR7
#define Gpio_GetLevelP14()     AP_GPIO->IDR_f.IDR8
#define Gpio_GetLevelP15()     AP_GPIO->IDR_f.IDR9
#define Gpio_GetLevelP16()     AP_GPIO->IDR_f.IDR10
#define Gpio_GetLevelP17()     AP_GPIO->IDR_f.IDR11
#define Gpio_GetLevelP18()     AP_GPIO->IDR_f.IDR12
#define Gpio_GetLevelP20()     AP_GPIO->IDR_f.IDR13
#define Gpio_GetLevelP23()     AP_GPIO->IDR_f.IDR14
#define Gpio_GetLevelP24()     AP_GPIO->IDR_f.IDR15
#define Gpio_GetLevelP25()     AP_GPIO->IDR_f.IDR16
#define Gpio_GetLevelP26()     AP_GPIO->IDR_f.IDR17
#define Gpio_GetLevelP27()     AP_GPIO->IDR_f.IDR18
#define Gpio_GetLevelP31()     AP_GPIO->IDR_f.IDR19
#define Gpio_GetLevelP32()     AP_GPIO->IDR_f.IDR20
#define Gpio_GetLevelP33()     AP_GPIO->IDR_f.IDR21
#define Gpio_GetLevelP34()     AP_GPIO->IDR_f.IDR22


#endif
